其他
ollvm算法还原案例分享
本文为看雪论坛优秀文章
看雪论坛作者ID:咸鱼炒白菜
本文为看雪安卓高研3w班(5月班)优秀学员作品。
下面先让我们来看看讲师对学员学习成果的点评,以及学员的学习心得吧!
分析被ollvm混淆的算法思路就是找到参数被加密的过程以及结果的生成过程,frida的Thread.backtrace得到调用栈可以快速分析出参数的加密过程,再结合ida trace可以分析出参数被加密的具体算法。
trace日志太大的时候,参数加密过程比较多,可以从trace日志中找返回结果的生成过程,来定位到具体算法的地址。
样本来自看雪3W班5月题。
本题主要是还原so的算法函数,关键算法函数很好定位,主要还原方法是frida+ida调试+ida trace。
现在,看雪《安卓高级研修班(网课)》9月班开始招生啦!点击查看详情报名吧~
1
解题步骤
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("native-lib");
}
public native byte[] d(byte[] arg1) {
}
public native byte[] e(byte[] arg1) {
}
@Override // androidx.appcompat.app.AppCompatActivity
protected void onCreate(Bundle arg3) {
super.onCreate(arg3);
this.setContentView(0x7F09001C); // layout:activity_main
TextView v3 = (TextView)this.findViewById(0x7F070061); // id:sample_text
StringBuilder v0 = new StringBuilder();
v0.append("pediy_imyang_");
v0.append(RandomStringUtils.randomAlphabetic(10));
v3.setText(ByteString.of(this.e(v0.toString().getBytes())).hex());
}
}
function hook_java(){
Java.perform(function () {
//org.apache.commons.lang3.RandomStringUtils.randomAlphabetic(int): java.lang.String
var RandomStringUtils = Java.use("org.apache.commons.lang3.RandomStringUtils");
RandomStringUtils.randomAlphabetic.overload('int').implementation = function(arg){
var result = this.randomAlphabetic(arg);
// console.log("org.apache.commons.lang3.RandomStringUtils.randomAlphabetic:", result);
result = "lXcaTALmow";
return result;
}
//com.kanxue.ollvm5.MainActivity.encryt(byte[]): byte[]
var ByteString = Java.use("com.android.okhttp.okio.ByteString");
var MainActivity = Java.use("com.kanxue.ollvm5.MainActivity");
MainActivity.e.implementation = function(arg){
var result = this.e(arg);
console.log("com.kanxue.ollvm5.MainActivity arg:", ByteString.of(arg).hex());
console.log("com.kanxue.ollvm5.MainActivity result:", ByteString.of(result).hex());
return result;
}
});
}
com.kanxue.ollvm5.MainActivity arg: 70656469795f696d79616e675f6c58636154414c6d6f77
com.kanxue.ollvm5.MainActivity result: 797903090001a4b8b6c89eb47f4f29b44d47c7382f851ad57618f9b820c5d55298cb5f941c8c
sub_184EC(&arg0, arg1, arg2);
`
__int64 __fastcall sub_13CE4(__int64 result, unsigned int a2, __int64 a3, unsigned int a4, __int64 output)
//13CE4
var addr_13CE4 = base.add(0x13CE4);
var arg13CE4_0;
var arg13CE4_1;
var arg13CE4_4;
Interceptor.attach(addr_13CE4, {
onEnter: function (args) {
//var r2 = this.context.r2;
arg13CE4_0 = args[0];
arg13CE4_1 = args[1];
arg13CE4_4 = args[4];
console.log("addr_13CE4 onEnter args0", hexdump(args[0])); //input
console.log("addr_13CE4 onEnter args1", args[1]); //inputlen
console.log("addr_13CE4 onEnter args4", hexdump(args[4]));
},
onLeave: function (retval) {
console.log("addr_13CE4 onLeave args0", hexdump(arg13CE4_0));
console.log("addr_13CE4 onLeave args1", arg13CE4_1);
console.log("addr_13CE4 onLeave args4", hexdump(arg13CE4_4));
// console.log("addr_13CE4 retval", hexdump(arg1));
}
});
function call_e() {
//主动调用函数
//com.kanxue.ollvm5.MainActivity.e(byte[]): byte[]
Java.perform(function () {
var MainActivity = Java.use("com.kanxue.ollvm5.MainActivity");
Java.choose("com.kanxue.ollvm5.MainActivity", {
onMatch: function (instance) {
//pediy_imyang_lXcaTALmow
var buffer = Java.array('byte', [0x70, 0x65, 0x64, 0x69, 0x79, 0x5f, 0x69, 0x6d, 0x79, 0x61, 0x6e, 0x67, 0x5f, 0x6c, 0x58, 0x63, 0x61, 0x54, 0x41, 0x4c, 0x6d, 0x6f, 0x77])
var result = instance.e(buffer);
var ByteString = Java.use("com.android.okhttp.okio.ByteString");
console.log(ByteString.of(result).hex())
},
onComplete: function () {
}
});
});
}
[AOSP on msm8996::com.kanxue.ollvm5]-> android_dlopen_ext: /data/app/com.kanxue.ollvm5-BHVsEeMGCcVFJqvmRywKWw==/lib/arm64/libnative-lib.so
addr_13CE4 onEnter args0 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
71103c3940 70 65 64 69 79 5f 69 6d 79 61 6e 67 5f 6c 58 63 pediy_imyang_lXc
71103c3950 61 54 41 4c 6d 6f 77 00 63 74 69 76 69 74 79 00 aTALmow.ctivity.
71103c3960 60 74 22 10 71 00 00 00 a0 3a 3c 10 71 00 00 00 `t".q....:<.q...
71103c3970 d8 2e 07 05 71 00 00 00 7a 69 70 3a 00 00 00 00 ....q...zip:....
71103c3980 40 39 3c 10 71 00 00 00 78 2f f9 1f b9 bb 45 f9 @9<.q...x/....E.
71103c3990 88 61 d2 6f 00 00 00 00 01 69 70 3a 0d 00 00 00 .a.o.....ip:....
71103c39a0 e0 38 3c 10 71 00 00 00 c2 0c ec de f4 c9 52 69 .8<.q.........Ri
71103c39b0 b0 72 20 f7 70 00 00 00 01 69 70 3a 0e 00 00 00 .r .p....ip:....
71103c39c0 e0 39 3c 10 71 00 00 00 9c 37 53 f8 65 b6 7c 4b .9<.q....7S.e.|K
71103c39d0 e0 72 20 f7 70 00 00 00 01 69 70 3a 0f 00 00 00 .r .p....ip:....
71103c39e0 80 39 3c 10 71 00 00 00 3c 06 6b 29 07 5f ca 6f .9<.q...<.k)._.o
71103c39f0 10 73 20 f7 70 00 00 00 01 69 70 3a 10 00 00 00 .s .p....ip:....
71103c3a00 c0 39 3c 10 71 00 00 00 db 0c 87 26 01 e5 1f 47 .9<.q......&...G
71103c3a10 40 73 20 f7 70 00 00 00 01 69 70 3a 11 00 00 00 @s .p....ip:....
71103c3a20 60 39 3c 10 71 00 00 00 93 20 5d c7 0a 4f 29 a9 `9<.q.... ]..O).
71103c3a30 78 c7 c5 6f 00 00 00 00 e0 c9 38 10 71 00 00 00 x..o......8.q...
addr_13CE4 onEnter args1 0x17
addr_13808 onEnter args0 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
79ff4fd210 77 77 77 2e 70 65 64 69 79 2e 63 6f 6d 26 6b 61 www.pediy.com&ka
79ff4fd220 6e 78 75 65 00 00 00 00 79 79 00 00 00 00 00 00 nxue....yy......
79ff4fd230 62 61 73 69 63 5f 73 74 72 69 6e 67 00 00 00 00 basic_string....
79ff4fd240 61 6c 6c 6f 63 61 74 6f 72 3c 54 3e 3a 3a 61 6c allocator<T>::al
addr_13808 onEnter args1 0x14
addr_13808 onLeave args2 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
7fdcb5fe70 31 f5 f5 f5 f9 43 4d 51 a8 fb 31 b6 ef 7f f7 3c 1....CMQ..1....<
7fdcb5fe80 40 ba 21 9d 7a 00 00 00 17 00 00 00 00 00 00 00 @.!.z...........
7fdcb5fe90 46 9d 4c 18 7a 00 00 00 00 00 00 00 09 00 00 00 F.L.z...........
7fdcb5fea0 60 75 49 18 7a 00 00 00 40 9d 4c 18 17 00 00 00 `uI.z...@.L.....
7fdcb5feb0 10 d2 4f ff 79 00 00 00 14 00 00 00 00 00 00 00 ..O.y...........
addr_172D0 onEnter args0 0xb6cff93c
addr_172D0 onLeave retval 0xcff93cb6
addr_172D0 onEnter args0 0xb6ef9f85
addr_172D0 onLeave retval 0x9f85b6ef
addr_172D0 onEnter args0 0xcf506afb
addr_172D0 onLeave retval 0xfbcf506a
addr_172D0 onEnter args0 0x3ca8f563
addr_172D0 onLeave retval 0xa8f5633c
addr_172D0 onEnter args0 0x63636363
addr_172D0 onLeave retval 0x63636363
addr_172D0 onEnter args0 0x63636363
addr_172D0 onLeave retval 0x63636363
addr_13CE4 onLeave args4 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
71102c8e70 79 79 03 09 00 01 a4 b8 b6 c8 9e b4 7f 4f 29 b4 yy...........O).
71102c8e80 4d 47 c7 38 2f 85 1a d5 76 18 f9 b8 20 c5 d5 52 MG.8/...v... ..R
71102c8e90 98 cb 5f 94 1c 8c 38 3c 55 0b 00 00 00 00 00 00 .._...8<U.......
71102c8ea0 4a 61 76 61 5f 63 6f 6d 5f 6b 61 6e 78 75 65 5f Java_com_kanxue_
71102c8eb0 6f 6c 6c 76 6d 35 5f 4d 61 69 6e 41 63 74 69 76 ollvm5_MainActiv
71102c8ec0 69 74 79 5f 65 00 00 00 56 0b 00 00 00 00 00 00 ity_e...V.......
71102c8ed0 80 a2 2c 10 71 00 00 00 71 54 b6 27 19 57 c7 d8 ..,.q...qT.'.W..
71102c8ee0 00 00 00 00 00 00 00 00 db d0 cf 94 71 00 00 00 ............q...
71102c8ef0 0e 00 00 00 00 00 00 00 57 0b 00 00 00 00 00 00 ........W.......
71102c8f00 10 a6 2c 10 71 00 00 00 3b 29 67 2f d8 63 3f 36 ..,.q...;)g/.c?6
71102c8f10 00 00 00 00 00 00 00 00 01 d1 cf 94 71 00 00 00 ............q...
71102c8f20 13 00 00 00 00 00 00 00 b8 0b 00 00 00 00 00 00 ................
71102c8f30 00 8f 2c 10 71 00 00 00 12 6d 28 cd 75 ae c6 d4 ..,.q....m(.u...
71102c8f40 00 00 00 00 00 00 00 00 25 d1 cf 94 71 00 00 00 ........%...q...
71102c8f50 18 00 00 00 00 00 00 00 c2 0b 00 00 00 00 00 00 ................
71102c8f60 90 95 2c 10 71 00 00 00 52 af da eb a8 27 dd ed ..,.q...R....'..
com.kanxue.ollvm5.MainActivity arg: 70656469795f696d79616e675f6c58636154414c6d6f77
com.kanxue.ollvm5.MainActivity result: 797903090001a4b8b6c89eb47f4f29b44d47c7382f851ad57618f9b820c5d55298cb5f941c8c
79 79 03 09 00 01
51 4D 43 F9
B6 CF F9 3C
B6 EF 9F 85
CF 50 6A FB
EF 20 83 29
3C A8 F5 63
63 63 63 63
63 63 63 63
79 79 03 09 00 01
a4 b8 b6 c8
9e b4 7f 4f
29 b4 4d 47
c7 38 2f 85
1a d5 76 18
f9 b8 20 c5
d5 52 98 cb
5f 94 1c 8c
static char keytb_42210[] = {
0x77, 0x77, 0x77, 0x2e,
0x70, 0x65, 0x64, 0x69,
0x79, 0x2e, 0x63, 0x6f,
0x6d, 0x26, 0x6b, 0x61,
0x6e, 0x78, 0x75, 0x65, 0x00
};
static char keytbde[] = {
0x31, 0xf5, 0xf5, 0xf5,
0xf9, 0x43, 0x4d, 0x51,
0xa8, 0xfb, 0x31, 0xb6,
0xef, 0x7f, 0xf7, 0x3c,
0x40, 0xba, 0x21, 0x9d,
0x7a, 0x00
};
static char byte_42228[] = {0x79, 0x79, 0x00, 0x00};
static char byte_42108[] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30,
0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82,
0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2,
0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26,
0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71,
0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96,
0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2,
0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53,
0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb,
0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa,
0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,
0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92,
0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff,
0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44,
0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46,
0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32,
0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac,
0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65,
0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6,
0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b,
0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1,
0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e,
0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89,
0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,
0xb0, 0x54, 0xbb, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00
};
void sub_13808(char* tb, int tblen, char* output){
//本函数从keytb_42210 解析出 keytbde
}
int REV(int val){
return (((val << 24) & 0xFF000000) | ((val << 8) & 0x00FF0000) | ((val >> 8) & 0x0000FF00) | ((val >> 24) & 0x000000FF));
}
int keygen_13CE4(const char* input, unsigned int inputlen, char* tb, unsigned int tblen, char* output){
char* o13808 = new char[0x20];
sub_13808(tb, tblen, o13808);
output[0] = byte_42228[0];
//LOGD("%0x %0x",0, output[0]);
output[1] = byte_42228[1];
output[2] = 0x03;
output[3] = (-inputlen ^ 0xFFFFFFF0) & -inputlen;;
output[4] = 0;
output[5] = 1;
//LOGD("%0x %0x",3, output[3]);
//LOGD("%0x %0x",4, output[4]);
for(int i = 6; i <= 0x25; i++){
int index = input[i - 6];
if(i - 6 >= inputlen){
output[i] = byte_42108[0];
//LOGD("%0x %0x",i, output[i]);
continue;
}
output[i] = byte_42108[index];
//LOGD("%0x %0x",i, output[i]);
}
for(int i = 0; i < tblen; i++){
int index = tb[i];
tb[i] = byte_42108[index];
//LOGD("tb %0x %0x",i, tb[i]);
}
for(int i = 0; i <= (0x25 - 0x6)/4; i++){
unsigned int tmp1 = 0;
memcpy(&tmp1, keytbde+4*(i%4), sizeof(int));
//LOGD("tmp1 %0x", tmp1);
unsigned int tmp2 = 0;
memcpy(&tmp2, output + i*4 + 6, sizeof(int));
//LOGD("tmp2 %0x", tmp2);
tmp2 = (tmp2 >> 8*(i%4)) | (tmp2 << 32 - 8*(i%4));
//LOGD("tmp2 %0x", tmp2);
tmp2 = REV(tmp2);
int outputtmp = REV(tmp1 & ~tmp2 | tmp2 & ~tmp1);
LOGD("outputtmp %0x", outputtmp);
memcpy(output+(6+i*4), &outputtmp, sizeof(int));
}
for(int i=0; i<=0x25; i++){
LOGD("output %0x %0x", i, output[i]);
}
return 0;
}
void main(){
int tblen = strlen(keytb);
const char* input = "pediy_imyang_lXcaTALmow";
char* output = new char[0x200];
keygen_13CE4(input, strlen(input), keytb_42210, tblen, output);
}
看雪ID:咸鱼炒白菜
https://bbs.pediy.com/user-752228.htm
*本文由看雪论坛 咸鱼炒白菜 原创,转载请注明来自看雪社区。
推荐文章++++
好书推荐